/**
 * Team members:
 * HengXing Liu 2022229044
 * YiYang Zhang 2022229047
 * ZeJun Liu 2022229092
 */
package project;

/**
 * A class for the tokens returned by a tokenizer.
 * A token is an atomic unit read from the user input.
 * YOU MUST COMPLETE AND USE THIS CLASS WITHOUT CHANGING
 * THE PUBLIC METHODS
 */
public class Token {

	private String data;
	private boolean isNum;
	private boolean isStr;
	private boolean isIdt;
	private boolean isDel;
	private boolean isOpr;
	private boolean isEqu;

	/**
	 * checks if this is the token '='
	 */
	public boolean isEqual() {
		return isEqu;
	}

	/**
	 * checks if this is a number token
	 */
	public boolean isNumber() {
		return isNum;
	}

	/**
	 * if this is a number token, returns the
	 * number as a double, throws a TokenException
	 * otherwise
	 */
	public double getNumber() throws TokenException {
		if(isNum){
			return Double.parseDouble(data);
		}else{
			throw new TokenException(data + " is not number token");
		}
	}

	/**
	 * checks if this is a string token
	 */
	// what is string token
	public boolean isString() {
		return isStr;
	}

	/**
	 * if this is a string token, returns the
	 * string as a String, throws a TokenException
	 * otherwise
	 */
	public String getString() throws TokenException {
		if(isStr){
			return data;
		}else{
			throw new TokenException(data + " is not string token");
		}
	}

	/**
	 * checks if this is an identifier token
	 */
	// where/how to check variable
	public boolean isIdentifier() {
		return isIdt;
	}

	/**
	 * if this is an identifier token, returns the
	 * identifier as a String, throws a TokenException
	 * otherwise
	 */
	public String getIdentifier() throws TokenException {
		if(isIdt){
			return data;
		}else{
			throw new TokenException(data + " is not identifier token");
		}
	}

	/**
	 * checks if this is a delimiter token
	 */
	// what is delimiter
	public boolean isDelimiter() {
		return isDel;
	}

	/**
	 * if this is a delimiter token, returns the
	 * delimiter as a String, throws a TokenException
	 * otherwise
	 */
	public String getDelimiter() throws TokenException {
		if(isDel){
			return data;
		}else{
			throw new TokenException(data + " is not delimiter token");
		}
	}

	/**
	 * checks if this is an operator token
	 */
	public boolean isOperator() {
		return isOpr;
	}

	/**
	 * if this is an operator token, returns the
	 * operator as a String, throws a TokenException
	 * otherwise
	 */
	public String getOperator() throws TokenException {
		if(isOpr){
			return data;
		}else{
			throw new TokenException(data + " is not operator token");
		}
	}

	/**
	 * returns a string representation
	 * of the token this
	 */
	public String toString() {
		return data;
	}
	
	///// These methods are used to create tokens. You need
	///// to use these methods in the class Tokenizer. Each
	///// method is used to create a specific token of a 
	///// specific type. The methods are not commented because
	///// the name of the method says it all.
	
	public static Token makeNUMBER(double number) {
		Token ret = new Token(String.valueOf(number));
		ret.isNum = true;
		return ret;
	}
	public static Token makeIDENTIFIER(String string) {
		Token ret = new Token(string);
		ret.isIdt = true;
		return ret;
	}
	public static Token makeSTRING(String string) {
		Token ret = new Token(string);
		ret.isStr = true;
		return ret;
	}
	public static Token makeEQUAL() {
		Token ret = new Token("=");
		ret.isEqu = true;
		return ret;
	}
	public static Token makeOPENPAR() {
		Token ret = new Token("(");
		ret.isOpr = true;
		return ret;
	}
	public static Token makeCLOSEPAR() {
		Token ret = new Token(")");
		ret.isOpr = true;
		return ret;
	}
	public static Token makeCOMMA() {
		Token ret = new Token(",");
		ret.isDel = true;
		return ret;
	}
	public static Token makeMINUS() {
		Token ret = new Token("-");
		ret.isOpr = true;
		return ret;
	}
	public static Token makeUNARYMINUS() {
		Token ret = new Token("-U");
		ret.isOpr = true;
		return ret;
	}
	public static Token makeTIMES() {
		Token ret = new Token("*");
		ret.isOpr = true;
		return ret;
	}
	public static Token makeDIVIDE() {
		Token ret = new Token("/");
		ret.isOpr = true;
		return ret;
	}
	public static Token makePOWER() {
		Token ret = new Token("^");
		ret.isOpr = true;
		return ret;
	}
	public static Token makePLUS() {
		Token ret = new Token("+");
		ret.isOpr = true;
		return ret;
	}
	
	////// add your private methods below
	private Token(String data) {
		this.data = data;
	}
}
